package cn.iocoder.yudao.module.mzt.service.article;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mzt.dal.dataobject.articletag.ArticleTagDO;
import cn.iocoder.yudao.module.mzt.dal.mysql.articletag.ArticleTagMapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.mzt.controller.admin.article.vo.*;
import cn.iocoder.yudao.module.mzt.dal.dataobject.article.ArticleDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.mzt.dal.mysql.article.ArticleMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mzt.enums.ErrorCodeConstants.*;

/**
 * 文章 Service 实现类
 *
 * @author Geordie
 */
@Service
@Validated
public class ArticleServiceImpl implements ArticleService {

    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private ArticleTagMapper articleTagMapper;
    @Override
    public Long createArticle(ArticleSaveReqVO createReqVO) {
        // 插入
        ArticleDO article = BeanUtils.toBean(createReqVO, ArticleDO.class);
        saveArticleBind(createReqVO.getId(), createReqVO.getTagIds());
        // 返回
        return article.getId();
    }

    @Override
    public void updateArticle(ArticleSaveReqVO updateReqVO) {
        // 校验存在
        validateArticleExists(updateReqVO.getId());
        // 更新
        ArticleDO updateObj = BeanUtils.toBean(updateReqVO, ArticleDO.class);
        articleMapper.updateById(updateObj);
        deleteArticleBind(updateReqVO.getId());
        saveArticleBind(updateReqVO.getId(), updateReqVO.getTagIds());
    }

    @Override
    public void deleteArticle(Long id) {
        // 校验存在
        validateArticleExists(id);
        // 删除
        articleMapper.deleteById(id);
        deleteArticleBind(id);
    }

    private void validateArticleExists(Long id) {
        if (articleMapper.selectById(id) == null) {
            throw exception(ARTICLE_NOT_EXISTS);
        }
    }

    @Override
    public ArticleDO getArticle(Long id) {
        ArticleDO articleDO = articleMapper.selectById(id);
        List<ArticleTagDO> tagDOS = articleTagMapper.selectList(ArticleTagDO::getArticleId, id);
        articleDO.setTagIds(CollectionUtils.convertList(tagDOS, ArticleTagDO::getTagId));
        return articleDO;
    }

    @Override
    public PageResult<ArticleDO> getArticlePage(ArticlePageReqVO pageReqVO) {
        // 查询总数
        Long count = articleMapper.selectCount(new LambdaQueryWrapperX<ArticleDO>()
                .likeIfPresent(ArticleDO::getTitle, pageReqVO.getTitle())
                .likeIfPresent(ArticleDO::getSummary, pageReqVO.getSummary())
                .eqIfPresent(ArticleDO::getStatus, pageReqVO.getStatus())
                .eqIfPresent(ArticleDO::getRecommend, pageReqVO.getRecommend())
                .likeIfPresent(ArticleDO::getSeoTitle, pageReqVO.getSeoTitle())
                .likeIfPresent(ArticleDO::getSeoKeywords, pageReqVO.getSeoKeywords())
                .likeIfPresent(ArticleDO::getSeoDescription, pageReqVO.getSeoDescription())
                .betweenIfPresent(ArticleDO::getCreateTime, pageReqVO.getCreateTime())
                .likeIfPresent(ArticleDO::getCategoryName, pageReqVO.getCategoryName()));

        // 如果总数为 0,直接返回空
        if (count == 0) {
            return new PageResult<>(Collections.emptyList(), count);
        }

        // 实际分页查询
        List<ArticleDO> list = articleMapper.selectPageWithRelations(pageReqVO);
        return new PageResult<>(list, count);
    }
    /**
     * 文章绑定分类、标签信息
     *
     * @param articleId
     * @param tagIds
     */
    void saveArticleBind(Long articleId,  List<Long> tagIds) {

            if (CollUtil.isNotEmpty(tagIds)){
                List<ArticleTagDO> articleTagList = CollectionUtils.convertList(tagIds, tagId -> {
                    ArticleTagDO articleTag = new ArticleTagDO();
                    articleTag.setArticleId(articleId);
                    articleTag.setTagId(tagId);
                    return articleTag;
                });
                articleTagMapper.insert(articleTagList);
            }
        }
    /**
     * 文章删除绑定信息
     *
     * @param articleId
     */
    void deleteArticleBind(Long articleId) {
        articleTagMapper.deleteByArticleId(articleId);

    }
}
